﻿using System;
using System.IO;
using BuildVersionIncrement.Incrementors;
using SharpSvn;

namespace HappyTurtle.SvnVersionIncrementor
{
    /// There are some things to be aware of when using this incrementer.
    /// 
    /// SvnLatestCommitIncrementer relies on the SharpSvn library to pull
    /// the information it needs.  Because SharpSvn is a full SVN client underneath
    /// the covers, it will behave as such.  This means that if it encounters a working copy
    /// that is outdated, it may upgrade the working copy when it is used.
    /// This could result in the unexpected effect of having your normal SVN client not
    /// know how to read the working copy if it is outdated.  For more info, see: 
    /// http://subversion.tigris.org/faq.html#working-copy-format-change
    /// 
    /// Conversely, if the SharpSvn library being used in Build Version Increment becomes outdated,
    /// it may no longer be able to read the working copy and have to be updated in order to work again.
    /// 
    /// So the rule of thumb here is: keep the SVN clients up to date.
    /// 
    /// Another thing to be aware of is that this class is currently looking at the SVN information
    /// contained in the folder of the solution item - it will be getting the SVN information from 
    /// the directory that contains your project file.  We can consider adding settings so that
    /// the directory being used can be configured.
    /// 
    /// The number being used for the revision is the latest committed revision contained
    /// in the directory that contains the project.  In other words, it will return the latest
    /// revision where there was an actual change to the repository in this directory.
    /// If the entire repository is at revision 480, but the last change made to the directory
    /// that BVI is dealing with is revision 370, it will use 370.
    /// This should help to identify which components in a solution have changed, and which
    /// remain the same. (Assuming there's no breaking local changes.)

    /// <summary>
    /// Increments the version number by using the latest revision in an SVN working copy.
    /// </summary>
    public class SvnVersionIncrementor : BaseIncrementor
    {
        public override string Name
        {
            get { return "SVN Revision"; }
        }

        public override string Description
        {
            get { return "Gets the SVN revision number of the last commit in the project's directory."; }
        }

        public override int Increment(int value, DateTime buildStart, DateTime projectStart, string solutionFilePath)
        {
            // Get the full path to the directory that holds the solution file, so that it can be passed to the SvnClient.
            string slnFile = Path.GetFullPath(solutionFilePath);
            string directory;
            if (String.IsNullOrEmpty(Path.GetFileName(slnFile)))
                directory = slnFile;
            else
                directory = Path.GetDirectoryName(slnFile);

            return GetCurrentSVNRevision(directory);
        }

        int GetCurrentSVNRevision(string svnPath)
        {
            SvnClient svn = new SvnClient();
            SvnInfoEventArgs info;
            svn.GetInfo(SvnPathTarget.FromString(svnPath), out info);

            return (int)info.LastChangeRevision;
        }
    }
}
